package bll;

import java.sql.PreparedStatement;
import java.util.*;

import org.joda.time.DateTime;

import util.*;

import dal.*;
import model.*;

public class CommonBll {

	public static <T extends IModel> boolean checkInputs(T query) {
		// TODO
		return true;
	}

	public static QuotationModel loadFullQuotation(int id) throws Exception {
		QuotationModel quotation = null;

		{
			GenericDal<QuotationModel, QuotationModelExt> dal = new GenericDal<QuotationModel, QuotationModelExt>(new QuotationModel());
			QuotationModel query = new QuotationModel();
			query.setId(id);
			quotation = dal.select(query);
		}

		if (quotation != null) {
			loadOrganziedQuotationItems(quotation);
		}

		return quotation;
	}

	public static void loadOrganziedQuotationItems(QuotationModel quotation) throws Exception {
		GenericDal<QuotationItemModel, QuotationItemModelExt> dal = new GenericDal<QuotationItemModel, QuotationItemModelExt>(new QuotationItemModel());
		QuotationItemModelExt query = new QuotationItemModelExt();
		query.setIdQuotation(quotation.getId());

		List<QuotationItemModel> items = dal.selectList(query);

		List<QuotationItemModel> orderedItems = TreeUtil.organizeTree(items);

		quotation.setItems(orderedItems);
	}

	public static ChecklistModel loadFullChecklist(int id) throws Exception {
		ChecklistModel obj = null;

		{
			GenericDal<ChecklistModel, ChecklistModelExt> dal = new GenericDal<ChecklistModel, ChecklistModelExt>(new ChecklistModel());
			ChecklistModel query = new ChecklistModel();
			query.setId(id);
			obj = dal.select(query);
		}

		if (obj != null) {
			loadOrganziedChecklistItems(obj);
		}

		return obj;
	}

	public static void loadOrganziedChecklistItems(ChecklistModel obj) throws Exception {
		GenericDal<ChecklistItemModel, ChecklistItemModelExt> dal = new GenericDal<ChecklistItemModel, ChecklistItemModelExt>(new ChecklistItemModel());
		ChecklistItemModelExt query = new ChecklistItemModelExt();
		query.setIdChecklist(obj.getId());

		List<ChecklistItemModel> items = dal.selectList(query);

		List<ChecklistItemModel> orderedItems = TreeUtil.organizeTree(items);
		obj.setItems(orderedItems);
	}

	public static AgendaModel loadFullAgenda(int id) throws Exception {
		AgendaModel obj = null;

		{
			GenericDal<AgendaModel, AgendaModelExt> dal = new GenericDal<AgendaModel, AgendaModelExt>(new AgendaModel());
			AgendaModel query = new AgendaModel();
			query.setId(id);
			obj = dal.select(query);
		}

		if (obj != null) {
			GenericDal<AgendaItemModel, AgendaItemModelExt> dal = new GenericDal<AgendaItemModel, AgendaItemModelExt>(new AgendaItemModel());
			AgendaItemModelExt query = new AgendaItemModelExt();
			query.setIdAgenda(id);

			List<AgendaItemModel> items = dal.selectList(query);

			List<AgendaItemModel> orderedItems = TreeUtil.organizeTree(items);
			obj.setItems(orderedItems);
		}

		return obj;
	}

	public static void loadOrganziedAgendaItems(AgendaModel obj) throws Exception {
		GenericDal<AgendaItemModel, AgendaItemModelExt> dal = new GenericDal<AgendaItemModel, AgendaItemModelExt>(new AgendaItemModel());
		AgendaItemModelExt query = new AgendaItemModelExt();
		query.setIdAgenda(obj.getId());

		List<AgendaItemModel> items = dal.selectList(query);

		List<AgendaItemModel> orderedItems = TreeUtil.organizeTree(items);
		obj.setItems(orderedItems);
	}

	public static List<ProjectModel> loadProjectList(ProjectModelExt query) throws Exception {

		GenericDal<ProjectModel, ProjectModelExt> dal = new GenericDal<ProjectModel, ProjectModelExt>(new ProjectModel());

		List<ProjectModel> list = dal.selectList(query);

		if (query.getCountAgenda()) {

			GenericDal<AgendaModel, AgendaModelExt> agendaDal = new GenericDal<AgendaModel, AgendaModelExt>(new AgendaModel());

			for (ProjectModel obj : list) {
				AgendaModelExt agendaQuery = new AgendaModelExt();
				agendaQuery.setIdProject(obj.getId());
				int count = agendaDal.count(agendaQuery);
				obj.setAgendaCount(count);
			}
		}

		if (query.getCountQuotation()) {

			GenericDal<QuotationModel, QuotationModelExt> agendaDal = new GenericDal<QuotationModel, QuotationModelExt>(new QuotationModel());

			for (ProjectModel obj : list) {
				QuotationModelExt quotationQuery = new QuotationModelExt();
				quotationQuery.setIdProject(obj.getId());
				int count = agendaDal.count(quotationQuery);
				obj.setQuotationCount(count);
			}
		}

		if (query.getCountChecklist()) {

			GenericDal<ChecklistModel, ChecklistModelExt> checklistDal = new GenericDal<ChecklistModel, ChecklistModelExt>(new ChecklistModel());

			for (ProjectModel obj : list) {
				ChecklistModelExt checklistQuery = new ChecklistModelExt();
				checklistQuery.setIdProject(obj.getId());
				int count = checklistDal.count(checklistQuery);
				obj.setChecklistCount(count);
			}
		}

		if (query.getCountPhase()) {

			GenericDal<PhaseModel, PhaseModelExt> phaseDal = new GenericDal<PhaseModel, PhaseModelExt>(new PhaseModel());

			for (ProjectModel obj : list) {
				PhaseModelExt phaseQuery = new PhaseModelExt();
				phaseQuery.setIdProject(obj.getId());
				int count = phaseDal.count(phaseQuery);
				obj.setPhaseCount(count);
			}
		}

		return list;
	}

	public static List<QuotationModel> loadQuotationList(QuotationModelExt query) throws Exception {

		GenericDal<QuotationModel, QuotationModelExt> dal = new GenericDal<QuotationModel, QuotationModelExt>(new QuotationModel());

		List<QuotationModel> list = dal.selectList(query);

		if (query.getCountItem()) {

			GenericDal<QuotationItemModel, QuotationItemModelExt> agendaDal = new GenericDal<QuotationItemModel, QuotationItemModelExt>(new QuotationItemModel());

			for (QuotationModel obj : list) {
				QuotationItemModelExt agendaQuery = new QuotationItemModelExt();
				agendaQuery.setIdQuotation(obj.getId());
				int count = agendaDal.count(agendaQuery);
				obj.setItemCount(count);
			}
		}

		return list;
	}

	public static List<AgendaModel> loadAgendaList(AgendaModelExt query) throws Exception {

		GenericDal<AgendaModel, AgendaModelExt> dal = new GenericDal<AgendaModel, AgendaModelExt>(new AgendaModel());

		List<AgendaModel> list = dal.selectList(query);

		if (query.getCountItem()) {

			GenericDal<AgendaItemModel, AgendaItemModelExt> agendaDal = new GenericDal<AgendaItemModel, AgendaItemModelExt>(new AgendaItemModel());

			for (AgendaModel obj : list) {
				AgendaItemModelExt agendaQuery = new AgendaItemModelExt();
				agendaQuery.setIdAgenda(obj.getId());
				int count = agendaDal.count(agendaQuery);
				obj.setItemCount(count);
			}
		}

		return list;
	}

	public static List<ChecklistModel> loadChecklistList(ChecklistModelExt query) throws Exception {

		GenericDal<ChecklistModel, ChecklistModelExt> dal = new GenericDal<ChecklistModel, ChecklistModelExt>(new ChecklistModel());

		List<ChecklistModel> list = dal.selectList(query);

		if (query.getCountItem()) {

			GenericDal<ChecklistItemModel, ChecklistItemModelExt> agendaDal = new GenericDal<ChecklistItemModel, ChecklistItemModelExt>(new ChecklistItemModel());

			for (ChecklistModel obj : list) {
				ChecklistItemModelExt agendaQuery = new ChecklistItemModelExt();
				agendaQuery.setIdChecklist(obj.getId());
				int count = agendaDal.count(agendaQuery);
				obj.setItemCount(count);
			}
		}

		return list;
	}

	public static ProjectModel loadProjectWithPhases(int idProject) throws Exception {
		ProjectModel project = DalUtil.loadProject(idProject);

		List<PhaseModel> phases = DalUtil.loadPhaseByProject(idProject);
		Collections.sort(phases, new GenericComparator<PhaseModel>(PhaseModel.FieldNames.Index, false));
		project.setPhases(phases);

		List<ChecklistModel> checklists = DalUtil.loadChecklistByProject(idProject);

		for (ChecklistModel checklist : checklists) {
			List<ChecklistItemModel> items = DalUtil.loadChecklistItems(checklist.getId());
			checklist.setItems(items);
		}

		// organize items
		for (PhaseModel phase : phases) {
			for (ChecklistModel checklist : checklists) {
				List<ChecklistItemModel> items = ModelUtil.findChecklistItemByPhase(checklist.getItems(), phase.getId());
				List<ChecklistItemModel> orderedItems = TreeUtil.organizeTree(items);
				phase.getChecklistItems().addAll(orderedItems);
			}
		}

		DateTime firstDay = new DateTime(DateTimeUtil.getDayWithoutTime(project.getFirstDay()));
		DateTime lastDay = new DateTime(DateTimeUtil.getDayWithoutTime(project.getLastDay()));
		List<MonthInfo> months = DateTimeUtil.getMonthInRange(firstDay, lastDay);
		project.setMonths(months);

		return project;
	}

}
